﻿using System;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Xsl;


using System.Collections.Generic;

class Project : Form
{
    private TextBox txtResult;
    private ComboBox cbType;
    private TextBox txtSource;

    string XSLTPath = Environment.CurrentDirectory + "\\XSLT";

    public class ComboBoxItem
    {
        public string Name;
        public string EncodingType;
        public string FilePath;
        public System.Xml.Xsl.XslTransform XslTF;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="name">Format:(EncodingType)Name</param>
        /// <param name="filepath"></param>
        public ComboBoxItem(string name, string filepath)
        {
            int tagES=-1, tagEE=-1;
            for (int i = 0; i < name.Length; i++)
            {
                char c = name[i];
                if (c == '[' && tagES == -1) tagES = i+1;
                else if (c == ']' && tagES != -1 && tagEE == -1) tagEE = i;
            }
            if (tagES >= 0 && tagEE > tagES)
            {
                EncodingType = name.Substring(tagES, tagEE - tagES);
                Name = name.Substring(tagEE + 1);
            }
            else
            {
                EncodingType = "char";
                Name = name;
            }
            if (EncodingType == null || EncodingType.Length == 0)
            {
                EncodingType = "char";
            }
            FilePath = filepath;
            XslTF = new XslTransform();
            XslTF.Load(FilePath);
        }

        public override string ToString()
        {
            return Name;
        }
    }

    public List<ComboBoxItem> XSLTTemplates
    {
        get
        {
            List<ComboBoxItem> li = new List<ComboBoxItem>();
            if (Directory.Exists(XSLTPath))
                foreach (string p in Directory.GetFiles(XSLTPath, "*.xslt"))
                {
                    ComboBoxItem cbi = new ComboBoxItem(p.Substring(XSLTPath.Length + 1, p.Length - XSLTPath.Length - 6), p);
                    li.Add(cbi);
                }
            else
            {
                Directory.CreateDirectory(XSLTPath);
            }
            return li;
        }
    }

    public XmlDocument Document(string EncodingSource, string EncodingType)
    {
        XmlDocument xd = CreateNewXmlDocument();
        XmlElement root = xd.DocumentElement;
        if (EncodingType != null && EncodingType.Length > 0 && EncodingSource != null && EncodingSource.Length > 0)
        {
            if (EncodingType == "char")
            {
                foreach (char i in EncodingSource)
                {
                    XmlNode xs = xd.CreateElement("s");
                    XmlNode xc = xd.CreateElement("c");
                    xc.AppendChild(xd.CreateTextNode(((int)i).ToString()));
                    xs.AppendChild(xc);
                    root.AppendChild(xs);
                }
            }
            else
            {
                Encoding ec = Encoding.GetEncoding(EncodingType);
                foreach (char i in EncodingSource)
                {
                    XmlNode xs = xd.CreateElement("s");
                    foreach (byte j in ec.GetBytes(i.ToString()))
                    {
                        XmlNode xc = xd.CreateElement("c");
                        xc.AppendChild(xd.CreateTextNode(((int)j).ToString()));
                        xs.AppendChild(xc);
                    }
                    root.AppendChild(xs);
                }
            }
        }
        return xd;
    }

    public XmlDocument CreateNewXmlDocument()
    {
        XmlDocument xd = new XmlDocument();
        xd.LoadXml("<?xml version='1.0' encoding='utf-8'?><root />");
        return xd;
    }

    string INIPath = Environment.CurrentDirectory + "\\INI";

    public XmlDocument Ini
    {
        get
        {
            XmlDocument xd = new XmlDocument();
            if (File.Exists(INIPath + "\\config.xml"))
            {
                xd.Load(INIPath + "\\config.xml");
            }
            return xd;
        }
        set
        {
            if (!Directory.Exists(INIPath))
            {
                Directory.CreateDirectory(INIPath);
            }
            if (File.Exists(INIPath + "\\config.xml"))
            {
                value.Save(new FileStream(INIPath + "\\config.xml", FileMode.Truncate, FileAccess.Write, FileShare.Read));
            }
            else
            {
                value.Save(new FileStream(INIPath + "\\config.xml", FileMode.Create, FileAccess.Write, FileShare.Read));
            }
        }
    }

    [STAThread]
    static void Main()
    {
        Application.Run(new Project());
    }

    const string ConfigPath = "config.ini";

    public Project()
    {
        InitializeComponent();

        foreach (ComboBoxItem i in XSLTTemplates)
        {
            cbType.Items.Add(i);
        }

        XmlDocument xd = Ini;

        if (xd.DocumentElement != null)
        {
            foreach (XmlElement i in xd.DocumentElement)
            {
                if (i.Name == "xsltindex")
                {
                    int xsltindex;
                    if (i.FirstChild != null)
                        if (int.TryParse(i.FirstChild.Value, out xsltindex) && cbType.Items.Count > xsltindex - 1)
                            cbType.SelectedIndex = xsltindex;

                }
            }
        }
    }

    protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
    {
        XmlDocument xd = CreateNewXmlDocument();
        XmlNode xn;

        xn = xd.CreateElement("xsltindex");
        xn.AppendChild(xd.CreateTextNode(cbType.SelectedIndex.ToString()));
        xd.DocumentElement.AppendChild(xn);
        Ini = xd;
        base.OnClosing(e);
    }

    private void InitializeComponent()
    {
        this.txtSource = new System.Windows.Forms.TextBox();
        this.txtResult = new System.Windows.Forms.TextBox();
        this.cbType = new System.Windows.Forms.ComboBox();
        this.SuspendLayout();
        // 
        // txtSource
        // 
        this.txtSource.Location = new System.Drawing.Point(12, 39);
        this.txtSource.Multiline = true;
        this.txtSource.Name = "txtSource";
        this.txtSource.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
        this.txtSource.Size = new System.Drawing.Size(329, 116);
        this.txtSource.TabIndex = 0;
        this.txtSource.TextChanged += new System.EventHandler(this.txtSource_TextChanged);
        this.txtSource.Enter += new System.EventHandler(this.txtSource_Enter);
        // 
        // txtResult
        // 
        this.txtResult.Location = new System.Drawing.Point(12, 163);
        this.txtResult.Multiline = true;
        this.txtResult.Name = "txtResult";
        this.txtResult.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
        this.txtResult.Size = new System.Drawing.Size(329, 150);
        this.txtResult.TabIndex = 1;
        this.txtResult.Enter += new System.EventHandler(this.txtResult_Enter);
        // 
        // cbType
        // 
        this.cbType.FormattingEnabled = true;
        this.cbType.Location = new System.Drawing.Point(12, 12);
        this.cbType.Name = "cbType";
        this.cbType.Size = new System.Drawing.Size(329, 20);
        this.cbType.TabIndex = 5;
        // 
        // Project
        // 
        this.ClientSize = new System.Drawing.Size(353, 316);
        this.Controls.Add(this.cbType);
        this.Controls.Add(this.txtResult);
        this.Controls.Add(this.txtSource);
        this.Name = "Project";
        this.ResumeLayout(false);
        this.PerformLayout();

    }

    private void txtSource_TextChanged(object sender, EventArgs e)
    {
        ComboBoxItem cbi = cbType.SelectedItem as ComboBoxItem;
        if (cbi == null)
            return;
        XmlDocument xd = Document(txtSource.Text, cbi.EncodingType);
        xd.CreateNavigator();
        StringBuilder sb = new StringBuilder();
        cbi.XslTF.Transform(xd.CreateNavigator(), null, new StringWriter(sb), null);
        txtResult.Text = sb.ToString();
    }

    private void txtResult_Enter(object sender, EventArgs e)
    {
        Clipboard.SetData(DataFormats.Text, txtResult.Text);
    }

    private void txtSource_Enter(object sender, EventArgs e)
    {
        string txt = Clipboard.GetData(DataFormats.Text) as string;
        if (txt == null || txt.Length == 0 || txt == txtSource.Text)
            return;
        txtSource.Text = txt;
    }
}

